﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using UCS.XNA.Utils.Geometries;

namespace UCS.XNA.Utils.Physics
{
    public static class CollisionDetector
    {
        #region Static Methods

        public static bool TestFullCollision(IRectangle rectangle, Vector2 position)
        {
            return position.X >= rectangle.X && position.X <= rectangle.X + rectangle.Width &&
                   position.Y >= rectangle.Y && position.Y <= rectangle.Y + rectangle.Height;
        }

        public static bool TestFullCollision(Rectangle rectangle, Vector2 position)
        {
            return position.X >= rectangle.Left && position.X <= rectangle.Right &&
                   position.Y >= rectangle.Top && position.Y <= rectangle.Bottom;
        }

        public static bool TestFullCollision(ICircle circle, Vector2 position)
        {
            return Vector2.Distance(position, new Vector2(circle.X, circle.Y)) <= circle.Radius;
        }

        public static bool TestFullCollision(IRectangle rect, ICircle circle)
        {
            Vector2 tl = new Vector2(rect.X             , rect.Y);
            Vector2 tr = new Vector2(rect.X + rect.Width, rect.Y);
            Vector2 bl = new Vector2(rect.X             , rect.Y + rect.Height);
            Vector2 br = new Vector2(rect.X + rect.Width, rect.Y + rect.Height);
            Vector2 circleCenter = new Vector2(circle.X, circle.Y) + circle.Direction * circle.SpeedFactor;

            if (Vector2.Distance(tl, circleCenter) <= circle.Radius)
                return true;

            if (Vector2.Distance(tr, circleCenter) <= circle.Radius)
                return true;

            if (Vector2.Distance(bl, circleCenter) <= circle.Radius)
                return true;

            if (Vector2.Distance(br, circleCenter) <= circle.Radius)
                return true;

            return false;
        }

        public static bool TestBoundsCollision(IRectangle rectangle, Vector2 position)
        {
            throw new NotImplementedException();
        }

        public static bool TestBoundsCollision(IRectangle rectangleA, IRectangle rectangleB)
        {
            float leftA = rectangleA.X;
            float rightA = rectangleA.X + rectangleA.Width;
            float topA = rectangleA.Y;
            float bottomA = rectangleA.Y + rectangleA.Height;

            float leftB = rectangleB.X;
            float rightB = rectangleB.X + rectangleB.Width;
            float topB = rectangleB.Y;
            float bottomB = rectangleB.Y + rectangleB.Height;

            if (rightB >= leftA &&
                rightB <= rightA &&
                topB <= topA &&
                bottomB >= topA)
                return true;

            if (leftB >= leftA &&
                leftB <= rightA &&
                topB <= topA &&
                bottomB >= topA)
                return true;

            if (rightB >= leftA &&
                rightB <= rightA &&
                topB <= bottomA &&
                bottomB >= bottomA)
                return true;

            if (leftB >= leftA &&
                leftB <= rightA &&
                topB <= bottomA &&
                bottomB >= bottomA)
                return true;

            if (leftB <= leftA &&
                rightB >= leftA &&
                bottomB >= topA &&
                bottomB <= bottomA)
                return true;

            if (leftB <= leftA &&
                rightB >= leftA &&
                topB >= topA &&
                topB <= bottomA)
                return true;

            if (leftB <= rightA &&
                rightB >= rightA &&
                bottomB >= topA &&
                bottomB <= bottomA)
                return true;

            if (leftB <= rightA &&
                rightB >= rightA &&
                topB >= topA &&
                topB <= bottomA)
                return true;

            return false;
        }

        //public static Vector2 TestBoundsCollision(IRectangle rectangle, ICircle circle)
        //{
        //    var circleCenter = new Vector2(circle.X + circle.Radius, circle.Y + circle.Radius);
        //    if (circleCenter.X < rectangle.X)
        //    {
        //        if (circleCenter.Y < rectangle.Y)
        //            this.Collision // Q1
        //        else if (circleCenter.Y >= rectangle.Y && circleCenter.Y <= rectangle.Y + rectangle.Height)
        //            this.Collision // Q4
        //        else if (circleCenter.Y > rectangle.Y)
        //            this.Collision // Q7
        //    }
        //    else if (circleCenter.X >= rectangle.X && circleCenter.X <= rectangle.X + rectangle.Width)
        //    {
        //        if (circleCenter.Y < rectangle.Y)
        //            this.Collision // Q2
        //        else if (circleCenter.Y >= rectangle.Y && circleCenter.Y <= rectangle.Y + rectangle.Height)
        //            this.Collision // Q5
        //        else if (circleCenter.Y > rectangle.Y)
        //            this.Collision // Q8
        //    }
        //    else if (circleCenter.X >= rectangle.X && circleCenter.X <= rectangle.X + rectangle.Width)
        //    {
        //        if (circleCenter.Y < rectangle.Y)
        //            this.Collision // Q3
        //        else if (circleCenter.Y >= rectangle.Y && circleCenter.Y <= rectangle.Y + rectangle.Height)
        //            this.Collision // Q6
        //        else if (circleCenter.Y > rectangle.Y)
        //            this.Collision // Q9
        //    }

        //    return Vector2.Zero;
        //}

        #endregion
    }
}